package com.syni.mdd.yhd.common.all.service;

import com.syni.mdd.yhd.common.all.constants.Constants;
import com.syni.mdd.yhd.common.all.dao.jpa.BmsSearchLogDao;
import com.syni.mdd.yhd.common.all.entity.BmsSearchLog;
import com.syni.mdd.yhd.common.all.entity.BmsVideo;
import com.syni.mdd.yhd.common.all.service.impl.BaseService;
import com.syni.mdd.yhd.common.all.utils.SpecificationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;

/**
 * @className BmsUserOperationLogService
 * @description TOO
 * @Author cfx
 * @DATE 2019/4/9 12:04
 * @VERSION 1.0
 **/
@Service
public class BmsSearchLogService extends BaseService<BmsSearchLog, Integer> {

    @Value("${search.log.num}")
    private Integer num;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    BmsSearchLogDao bmsSearchLogDao;

    @Autowired
    BmsVideoService bmsVideoService;

    @Override
    public BmsSearchLogDao getBaseDao() {
        return bmsSearchLogDao;
    }

    public List<String> bmsSearchLogList(Integer userId,Integer searchNum){
        if(searchNum == null){
            searchNum = num;
        }
        List<String> searchList = new LinkedList<>();
        final Integer defaultPage = 1;
        Pageable pageable = PageRequest.of(defaultPage - 1,searchNum, Sort.Direction.DESC,"search_time");
        List<BmsSearchLog> bmsSearchLogs = bmsSearchLogDao.findByUserIdAndRecordType(userId,Constants.RECORD_TEXT,pageable);
        if(bmsSearchLogs != null && bmsSearchLogs.size() > 0){
            for(BmsSearchLog bmsSearchLog : bmsSearchLogs){
                searchList.add(bmsSearchLog.getSearchContent());
            }
        }
        return searchList;
    }

    public List<String> getUserSearchHot(Integer searchNum) {
        if(searchNum == null){
            searchNum = num;
        }
        Set<String> hotSearch = new HashSet<>();
        String redisKey = Constants.REDIS_KEY_PREFIX + "hostSearch";
        if(redisTemplate.hasKey(redisKey)) {
            //从redis中的zetset获取
            Set<String> set = redisTemplate.opsForZSet().reverseRange(redisKey,0,searchNum - 1);
            if(set != null && set.size() > 0){
                for(String bussessStr : set){
                    hotSearch.add(bussessStr);
                }
            }
        }
        if(hotSearch.size() < searchNum){
            //从数据库拿出最新的5条商家
            Map<String,Object> conditionMap = new HashMap<>();
            conditionMap.put("isRelease",Constants.COMMON_FLAG_FALSE_INT);
            conditionMap.put("isDelete",Constants.COMMON_FLAG_FALSE_INT);
            conditionMap.put("recommend",BmsVideoService.ALevel);
            conditionMap.put("isOff",Constants.COMMON_FLAG_FALSE_INT);
            if(hotSearch.size() > 0){
                conditionMap.put("vendorName_NIN", hotSearch);
            }

            List<BmsVideo> bmsVideos = bmsVideoService.getBaseDao().findAll(new SpecificationUtils(conditionMap),
                    PageRequest.of(1, searchNum - hotSearch.size(), Sort.Direction.DESC, "likeTimes")).getContent();
            if (bmsVideos.size() > 0) {
                for (BmsVideo bmsVideo : bmsVideos) {
                    hotSearch.add(bmsVideo.getVendorName());
                }
            }
        }
        return new ArrayList<>(hotSearch);
    }

    public void addUserSearchHistroy(Integer userId,String searchText,Integer searchType){
        BmsSearchLog bmsSearchLog = new BmsSearchLog();
        bmsSearchLog.setUserId(userId);
        bmsSearchLog.setSearchContent(searchText);
        bmsSearchLog.setSearchTime(new Date());
        bmsSearchLog.setRecordType(searchType);
        bmsSearchLogDao.save(bmsSearchLog);
    }

    @Transactional
    public void delUserSearchHistroy(Integer userId) {
        List<BmsSearchLog> bmsSearchLogs = bmsSearchLogDao.findByUserId(userId);
        if (bmsSearchLogs != null && bmsSearchLogs.size() > 0) {
            for (BmsSearchLog bmsSearchLog : bmsSearchLogs) {
                bmsSearchLogDao.delete(bmsSearchLog);
            }
        }
    }

    public void recordSearchClient(Integer userId, Integer businessId, Integer videoId) {
        BmsSearchLog bmsSearchLog = new BmsSearchLog();
        bmsSearchLog.setUserId(userId);
        bmsSearchLog.setVideoId(videoId);
        bmsSearchLog.setBusinessId(businessId);
        bmsSearchLog.setRecordType(Constants.RECORD_VIDEO_CLIENT);
        bmsSearchLog.setSearchTime(new Date());
        if(businessId != null){
            bmsSearchLog.setRecordType(Constants.RECORD_BUSINESS_CLIENT);
        }
        bmsSearchLogDao.save(bmsSearchLog);
    }
}
